package fr.laas.knxinterface.config;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

/**
 * This class loads all the important data to configure the program
 * 
 * @author Guillaume Garzone
 * 
 */
public class ServiceConfiguration {

	private static final String MissingIpRouteurKNX = "The IP of the IP/KNX router is missing";

	// allows to load the properties from the configuration file
	private Properties properties;
	// the path of the configuration file
	private String pathConfig = "config.properties";

	// ID of the data stored in the configuration file
	private String remoteHostNameId = "remoteHostName";
	private String dataSendingPortId = "dataSendingPort";
	private String commandsListeningPortId = "commandsListeningPort";
	private String ipRouteurKnxId = "ipRouteurKnx";

	// IMPORTANT DATA SAVED - default values
	private String remoteHostName = "localhost";
	private int dataSendingPort = 10081;
	private int commandsListeningPort = 10080;
	private String ipRouteurKnx = null;

	// to read / create the config file
	private FileInputStream fileStream;
	private FileOutputStream fileStreamOut;

	/**
	 * Constructor
	 */
	public ServiceConfiguration() {
		this.properties = new Properties();
	}

	/**
	 * @return the remoteHost
	 */
	public String getRemoteHost() {
		return remoteHostName;
	}

	/**
	 * @param remoteHost
	 *            the remoteHost to set
	 */
	public void setRemoteHost(String remoteHost) {
		this.remoteHostName = remoteHost;
	}

	/**
	 * @return the sendingPort
	 */
	public int getSendingPort() {
		return dataSendingPort;
	}

	/**
	 * @param sendingPort
	 *            the sendingPort to set
	 */
	public void setSendingPort(int sendingPort) {
		this.dataSendingPort = sendingPort;
	}

	/**
	 * @return the listeningPort
	 */
	public int getListeningPort() {
		return commandsListeningPort;
	}

	/**
	 * @param listeningPort
	 *            the listeningPort to set
	 */
	public void setListeningPort(int listeningPort) {
		this.commandsListeningPort = listeningPort;
	}

	public String getIpRouteurKnx() {
		return ipRouteurKnx;
	}

	public void storeProperties() {

		this.properties.setProperty(this.remoteHostNameId, this.remoteHostName);
		this.properties.setProperty(this.dataSendingPortId,
				Integer.toString(this.dataSendingPort));
		this.properties.setProperty(this.commandsListeningPortId,
				Integer.toString(this.commandsListeningPort));

		try {
			this.fileStreamOut = new FileOutputStream(new File(pathConfig));
			this.properties
					.store(this.fileStreamOut,
							"This file has been completed automatically with default values");
		} catch (FileNotFoundException e) {
			System.err
					.println("ERROR while creating config file : path is invalid");
			e.printStackTrace();
		} catch (IOException e) {
			System.err
					.println("ERROR while storing the configuration in the config file");
			e.printStackTrace();
		}

	}

	/**
	 * Loads the properties from the configuration file. If does not exist,
	 * create a knew one with default values
	 */
	public void loadProperties() {

		try {

			this.fileStream = new FileInputStream(this.pathConfig);
			this.properties.load(fileStream);

		} catch (FileNotFoundException e) {

			System.err.println("ERROR: config file not found");
			e.printStackTrace();

		} catch (IOException e) {

			System.err.println("ERROR while reading the configuration file");
			e.printStackTrace();

		} finally {

			// closing the file
			try {
				this.fileStream.close();
			} catch (IOException e) {
				System.err.println("ERROR while closing the file");
				e.printStackTrace();
			}
		}

		// saves the properties loaded
		try {
			this.saveProperties();
		} catch (Exception e) {
			System.err
					.println("Missing IP Routeur KNX. Please enter the IP in the configuration File.");
			e.printStackTrace();
		}
		this.storeProperties();

	}

	/**
	 * Saves the properties from the configuration file
	 * 
	 * @throws Exception
	 *             when ip router KNX is missing
	 */

	public void saveProperties() throws Exception {
		String tempS = null;
		// saving the new values loaded
		if (this.properties != null) {
			tempS = (String) this.properties.get(this.remoteHostNameId);
			if (tempS != null) {
				this.remoteHostName = tempS;
			}

			tempS = (String) this.properties.get(this.ipRouteurKnxId);
			if (tempS == null) {
				throw new Exception(MissingIpRouteurKNX);
			} else {
				this.ipRouteurKnx = tempS;
			}

			try {
				this.commandsListeningPort = Integer
						.parseInt((String) this.properties
								.get(this.commandsListeningPortId));
			} catch (NumberFormatException n) {
				System.out.println("Using default value for "
						+ this.commandsListeningPortId);
			}
			try {
				this.dataSendingPort = Integer
						.parseInt((String) this.properties
								.get(this.dataSendingPortId));
			} catch (NumberFormatException m) {
				System.out.println("Using default value for "
						+ this.dataSendingPortId);
			}
		}
	}

	/**
	 * Prints the properties loaded from the config file - above all for DEBUG
	 */
	public void printProperties() {
		if (this.properties != null) {
			System.out.println(this.properties.toString());
		}
	}

	/**
	 * Prints the data saved in the class (above all for debug)
	 */
	public void printData() {
		System.out.println(this.remoteHostName);
		System.out.println(this.commandsListeningPort);
		System.out.println(this.dataSendingPort);
		System.out.println(this.ipRouteurKnx);

	}

}
